﻿using Ldt.DataEngine.DataFlowParse.Model;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model;
using LdtJudge.DataEngine.Model.Collection;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.BaseModule
{
    public class AssermBase
    {
        /// <summary>
        /// 模块名称
        /// </summary>
        public string MoudleName { get; set; }
        /// <summary>
        /// 上下文
        /// </summary>
        public DataContext dataContext { get; set; }

        

        #region 解析配置
        public ConfigRootModel ParseStepConfig(ConfigModel configModel)
        {
            ConfigRootModel configRootModel = new ConfigRootModel();
            List<ConfigStateModel> configStatesList = new List<ConfigStateModel>();
            // 解析配置
            XmlDocument configDoc = new XmlDocument();
            configDoc.LoadXml(configModel.ConfigContent);
            XmlNode nodeRoot = configDoc.SelectSingleNode("root");
            if (nodeRoot.Attributes["type"]!=null)
            {
                configRootModel.type = nodeRoot.Attributes["type"].Value;
            }
            else
            {
                configRootModel.type = "0";
            }
            if (nodeRoot.Attributes["mlflag"]!=null)
            {
                configRootModel.mlflag = nodeRoot.Attributes["mlflag"].Value;
            }
            foreach (XmlNode node in configDoc.SelectSingleNode("root").ChildNodes)
            {
                ConfigStateModel configStateModel = new ConfigStateModel();
                configStateModel.executetype = node.Attributes["executetype"]?.Value;
                configStateModel.executefile = node.Attributes["executefile"]?.Value;
                configStateModel.code = node.Attributes["code"]?.Value;
                configStateModel.zh_cn = node.Attributes["zh_cn"]?.Value;
                configStateModel.executecode = node.Attributes["executecode"]?.Value;
                configStateModel.number = node.Attributes["number"]?.Value;
                configStatesList.Add(configStateModel);
                if (node.ChildNodes.Count > 0)
                {
                    foreach (XmlNode child in node.ChildNodes)
                    {
                        ParseStepNode(child, configStatesList);
                    }
                }
            }
            configRootModel.configStateModelList = configStatesList;
            return configRootModel;
        }

        /// <summary>
        /// 解析步骤节点
        /// </summary>
        /// <param name="stepNode"></param>
        private void ParseStepNode(XmlNode child,List<ConfigStateModel> configStates)
        {
            ConfigStateModel configStateModel = new ConfigStateModel();
            configStateModel.executetype = child.Attributes["executetype"]?.Value;
            configStateModel.executefile = child.Attributes["executefile"]?.Value;
            configStateModel.code = child.Attributes["code"]?.Value;
            configStateModel.zh_cn = child.Attributes["zh_cn"]?.Value;
            configStateModel.executecode = child.Attributes["executecode"]?.Value;
            configStateModel.number = child.Attributes["number"]?.Value;
            configStates.Add(configStateModel);
            if (child.ChildNodes.Count > 0)
            {
                foreach (XmlNode node in child.ChildNodes)
                {
                    ParseStepNode(node, configStates);
                }
            }
        }
        #endregion

        #region 提取模式处理
        /// <summary>
        /// 提取模式执行
        /// </summary>
        /// <param name="configStateModel"></param>
        public void ExeConfig(ConfigModel configStateModel, string ModelName)
        {
            if (configStateModel.ExecuteType == "reg")
            {

            }
            else if (configStateModel.ExecuteType == "dll")
            {
                try
                {
                    DynamicLoadingDLL(CommonFormat.GetCurrentProgramPath() + configStateModel.FilePath, ModelName);
                }
                catch (Exception ex)
                {


                }

            }
        }

        /// <summary>
        /// 动态加载DLL并执行
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="ClassName">类名</param>
        public void DynamicLoadingDLL(string path, string ClassName)
        {
            //实例化日志对象

            // 从远程服务上下载dll
            string localDllPath = DownloadDll(dataContext,path);
            if (string.IsNullOrEmpty(localDllPath))
            {
                return;
            }
            try
            {
                // 动态执行dll
                Assembly assem = Assembly.Load(File.ReadAllBytes(localDllPath));
                Type[] tys = assem.GetTypes();
                Type module = null;
                switch (ClassName.ToLower())
                {
                    case "persondialogextraction":
                        break;
                    case "elementdeduce":
                        break;
                    case "caseextraction":
                        break;
                    case "paragraph":
                        break;
                    case "personnelextraction":
                        module = assem.GetType("Ldt.DateEngine.Personnel.PersonnelStart");
                        break;
                    case "textformatting":
                        break;
                    case "caseCauseelementextraction":
                        break;
                }
                object Result = null;

                // 获取不带参数的构造函数
                ConstructorInfo magicConstructor = module.GetConstructor(Type.EmptyTypes);
                // 这里是获取一个类似于类的实例的东东
                object magicClassObject = magicConstructor.Invoke(new object[] { });
                // 获取提取方法
                MethodInfo mi = module.GetMethod("Extract");
                // 执行提取方法
                Result = mi.Invoke(magicClassObject, new object[] { dataContext.DataLayerAns });
                //dataContext.DataLayerAns = (DyData_Analysis)Result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            

        }

        /// <summary>
        /// 从远程服务器上下载dll文件
        /// </summary>
        /// <param name="dllRemotePath">dll远程地址</param>
        /// <returns>下载后的dll本地绝对路径</returns>
        public string DownloadDll(DataContext dataContext, string dllRemotePath)
        {
            try
            {
                // 根据path得到dll名称
                string dllName = Path.GetFileName(dllRemotePath);
                // 获取远程dll所在的目录
                string remotePath = Path.GetDirectoryName(dllRemotePath);
                // 下载dll后存放的目录
                string targetDir = CommonFormat.GetCurrentProgramPath() + remotePath.Substring(1);
                // 下载dll后，本地dll的绝对路径
                string targetDllFullPath = targetDir + @"\" + dllName;


                if (!Directory.Exists(targetDir))
                {
                    Directory.CreateDirectory(targetDir);
                }

                // 判断本地是否存在该dll，如果不存在就从配置管理平台下载到本地
                if (!File.Exists(targetDllFullPath))
                {
                    WebClient webClient = new WebClient();
                    string sourceUrl = ConfigRetrieval.GetConfigRetrieval.GetConnectionString("systemapi") + "/api/wordparse/GetDllFile?fileName=" + dllRemotePath;//ConfigRetrieval.GetConfigRetrieval.GetConnectionString("systemapi")
                    webClient.DownloadFile(sourceUrl, targetDllFullPath);
                }
                FileInfo fileInfo = new FileInfo(targetDllFullPath);
                if (fileInfo.Length == 0)
                {
                    dataContext.InteractiveShow.LogShow("dll文件大小为0，存在异常。错误发生在AssermBase.cs文件中。", LogMessageType.Debug);
                    File.Delete(targetDllFullPath);
                    return "";
                }
                // 将dll拷贝到程序目录下一份，方便程序调用(可能存在依赖所以放到程序根目录下)
                try
                {
                    if (File.Exists(CommonFormat.GetCurrentProgramPath() + dllName))
                    {
                        File.Delete(CommonFormat.GetCurrentProgramPath() + dllName);
                    }
                    File.Copy(targetDllFullPath, CommonFormat.GetCurrentProgramPath() + dllName);
                }
                catch (Exception e)
                {
                    dataContext.InteractiveShow.LogShow("删除拷贝文件时发生错误，错误发生在AssermBase.cs中删除拷贝文件部分：" + e.Message, LogMessageType.Error);
                }
                return CommonFormat.GetCurrentProgramPath() + dllName;
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("下载dll异常，错误信息" + ex.Message, LogMessageType.Debug);
            }
            return "";
        }

        #endregion
    }
}
